package com.ruoyi.extdata.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.ExtReqLog;
import com.ruoyi.bizsys.domain.ExtTransferResult;
import com.ruoyi.bizsys.domain.ExtTryQueue;
import com.ruoyi.bizsys.domain.RealNameAuth;
import com.ruoyi.bizsys.mapper.ExtTryQueueMapper;
import com.ruoyi.bizsys.service.IExtReqLogService;
import com.ruoyi.bizsys.service.IExtTransferResultService;
import com.ruoyi.bizsys.service.IRealNameAuthService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.extdata.common.Constants;
import com.ruoyi.extdata.common.TDAESUtil;
import com.ruoyi.extdata.common.config.*;
import com.ruoyi.extdata.domain.OkRequestVo;
import com.ruoyi.extdata.service.BaseService;
import com.ruoyi.extdata.service.IBankService;
import com.ruoyi.extdata.service.IExternalApiService;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.internal.http2.StreamResetException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Jamnsin
 * @Date: 2021/2/26 11:04 下午
 */
@Slf4j
@Service
public class ExternalApiServiceImpl extends BaseService implements IExternalApiService {

    @Autowired
    PayStackConfig payStackConfig;

    @Autowired
    OkraConfig okraConfig;

    @Autowired
    IExtReqLogService extReqLogService;

    @Autowired
    GoogleGeoMapConfig googleGeoMapConfig;

    @Autowired
    IExtTransferResultService transferResultService;

    @Autowired
    IBankService bankService;

    @Autowired
    RedisCache redisCache;

    @Autowired
    MonnifyConfig monnifyConfig;

    @Autowired
    IRealNameAuthService iRealNameAuthService;

    @Autowired
    RuleConfig ruleConfig;

    @Autowired
    ISysConfigService iSysConfigService;

    @Resource
    private OkHttpClient okHttpClient;

    @Autowired
    ExtTryQueueMapper extTryQueueMapper;

    public static final String NULL_DAYA = "response is null";

    //维度经度地址返解码接口
    @Override
    public JSONObject getGeocode(String latitude, String longitude) {

        JSONObject result = null;

        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("GetGeocode");
        extReqLog.setReqUrl(monnifyConfig.getAuthenticationUrl());

        //请求参数加工
        StringBuilder paramBuilder = new StringBuilder();
        //paramBuilder.append("language=en&result_type=street_address");
        paramBuilder.append("language=en&result_type=route");
        paramBuilder.append("&");
        paramBuilder.append("latlng=").append(latitude).append(",").append(longitude);
        paramBuilder.append("&");
        paramBuilder.append("key=").append(googleGeoMapConfig.getSecretKey());
        String param = paramBuilder.toString();

        extReqLog.setReqParam(param);
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        log.info("获取经纬度地址反解码：url = {}，param = {}", googleGeoMapConfig.getGeoUrl(), param);
        String rspStr = HttpUtils.sendGet(googleGeoMapConfig.getGeoUrl(), param, Constants.UTF8);

        String mock = getDictLable("biz_switch", "api_geoCode_mock");
        log.info("biz_switch - api_geoCode_mock = {}", mock);

        if ("1".equals(mock)) {
            rspStr = "{\"plus_code\":{\"compound_code\":\"2FJM+M9 Abuja, Nigeria\",\"global_code\":\"6FX92FJM+M9\"},\"results\":[{\"address_components\":[{\"long_name\":\"3\",\"short_name\":\"3\",\"types\":[\"street_number\"]},{\"long_name\":\"Funmilayo Ransome Kuti Road\",\"short_name\":\"Funmilayo Ransome Kuti Rd\",\"types\":[\"route\"]},{\"long_name\":\"Garki\",\"short_name\":\"Garki\",\"types\":[\"neighborhood\",\"political\"]},{\"long_name\":\"Abuja\",\"short_name\":\"Abuja\",\"types\":[\"locality\",\"political\"]},{\"long_name\":\"Abuja Municipal Area Council\",\"short_name\":\"AMAC\",\"types\":[\"administrative_area_level_2\",\"political\"]},{\"long_name\":\"Federal Capital Territory\",\"short_name\":\"Federal Capital Territory\",\"types\":[\"administrative_area_level_1\",\"political\"]},{\"long_name\":\"Nigeria\",\"short_name\":\"NG\",\"types\":[\"country\",\"political\"]}],\"formatted_address\":\"3 Funmilayo Ransome Kuti Rd, Garki, Abuja, Nigeria\",\"geometry\":{\"location\":{\"lat\":9.0314649,\"lng\":7.483429699999999},\"location_type\":\"ROOFTOP\",\"viewport\":{\"northeast\":{\"lat\":9.032813880291501,\"lng\":7.484778680291502},\"southwest\":{\"lat\":9.030115919708496,\"lng\":7.482080719708497}}},\"place_id\":\"ChIJ5eEsJYILThARQgg-8S-SuE0\",\"plus_code\":{\"compound_code\":\"2FJM+H9 Abuja, Nigeria\",\"global_code\":\"6FX92FJM+H9\"},\"types\":[\"street_address\"]}],\"status\":\"OK\"}";
        }

        extReqLog.setRspResult(rspStr);
        extReqLog.setCallStatus("0");

        if (StringUtils.isEmpty(rspStr)) {
            log.error("获取经纬度地址反解码异常 {}", param);
            extReqLog.setRetMsg("Return Null");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(RspEnmu.NETWORK_ERROR.getMessage() + "[Return Null]", RspEnmu.NETWORK_ERROR.getCode());
        }
        JSONObject obj = JSONObject.parseObject(rspStr);

        //结果处理
        if (null == obj.get("status") || !"OK".equals(obj.getString("status"))) {
            String statusStr = "null";
            if (null != obj.get("status")) {
                statusStr = obj.getString("status");
            }
            log.error("获取经纬度地址反解码结果状态status={}", statusStr);
            //ZERO_RESULTS反向地理编码成功，但未返回任何结果
            //OVER_QUERY_LIMIT超出配额
            //REQUEST_DENIED请求被拒绝
            //INVALID_REQUEST参数无效
            //UNKNOWN_ERROR 未知错误
            extReqLog.setRetMsg(statusStr);
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(RspEnmu.NETWORK_ERROR.getMessage() + "[" + statusStr + "]", RspEnmu.NETWORK_ERROR.getCode());
        }

        extReqLog.setCallStatus("1");
        extReqLog.setRetMsg("OK");
        extReqLogService.insertExtReqLog(extReqLog);

        if (null != obj.getJSONArray("results") && obj.getJSONArray("results").size() > 0) {
            JSONArray results = obj.getJSONArray("results");
            JSONObject resultObject = results.getJSONObject(0);

            result = new JSONObject();
            if (null != resultObject.get("formatted_address")) {
                result.put("address", resultObject.getString("formatted_address"));
            }
            Map<String, String> componentsMap = new HashMap<String, String>();
            if (null != resultObject.getJSONArray("address_components") && resultObject.getJSONArray("address_components").size() > 0) {
                JSONArray address_components = resultObject.getJSONArray("address_components");
                for (int i = 0; i < address_components.size(); i++) {
                    JSONObject components = address_components.getJSONObject(i);
                    if (null != components.get("types") && null != components.get("long_name")) {
                        if (components.getString("types").indexOf("political") > -1) {
                            if (components.getString("types").indexOf("country") > -1) {
                                componentsMap.put("country", components.getString("long_name"));
                            } else if (components.getString("types").indexOf("administrative_area_level_1") > -1) {
                                componentsMap.put("administrative_area_level_1", components.getString("long_name"));
                            } else if (components.getString("types").indexOf("administrative_area_level_2") > -1) {
                                componentsMap.put("administrative_area_level_2", components.getString("long_name"));
                            } else if (components.getString("types").indexOf("sublocality_level_1") > -1) {
                                componentsMap.put("sublocality_level_1", components.getString("long_name"));
                            } else if (components.getString("types").indexOf("locality") > -1) {
                                componentsMap.put("locality", components.getString("long_name"));
                            }
                        }
                    }
                }
            }
            if (componentsMap.size() > 0) {
                //国家
                if (null != componentsMap.get("country")) {
                    result.put("country", componentsMap.get("country"));
                }
                //省州
                if (null != componentsMap.get("administrative_area_level_1")) {
                    result.put("countryState", componentsMap.get("administrative_area_level_1"));
                }

                //市
                if (null != componentsMap.get("administrative_area_level_2")) {
                    result.put("city", componentsMap.get("administrative_area_level_2"));
                } else {
                    if (null != componentsMap.get("locality")) {
                        result.put("city", componentsMap.get("locality"));
                    } else {
                        result.put("city", componentsMap.get("sublocality_level_1"));
                    }
                }

                //区域
                if (null != componentsMap.get("administrative_area_level_2")) {
                    if (null != componentsMap.get("locality")) {
                        result.put("region", componentsMap.get("locality"));
                    } else {
                        result.put("region", componentsMap.get("sublocality_level_1"));
                    }
                } else {
                    if (null != componentsMap.get("sublocality_level_1")) {
                        result.put("region", componentsMap.get("sublocality_level_1"));
                    }
                }
            }
        }

        return result;
    }

    @Override
    public void dealTransferData(String eventType, String eventSource, String custNo, JSONObject data) {
        log.info("dealTransferData().eventType = {}，eventSource = {}", eventType, eventSource);

        ExtTransferResult transferResult = transferResultService.getOne(new QueryWrapper<ExtTransferResult>().eq("serial_no", data.getString("reference")).eq("state", Constants.BIZ_STATUS_1));
        if (Func.isEmpty(transferResult)) {
            saveExtTransferRst(data, eventType, eventSource, custNo);
            return;
        }

        if (!transferResult.getEventType().contains("success")) {
            updateExtTransferRst(transferResult.getId(), data, eventType, eventSource, custNo);
        }
    }


    @Override
    public void dealTransferData(String eventType, String eventSource, JSONObject data) {
        dealTransferData(eventType, eventSource, null, data);
    }

    @Override
    public String monnifyAuthLogin() {
        String token = redisCache.getCacheObject(Constants.MONNIFY_AUTHENTICATION_ACCESSTOKEN);

        if (token == null || StringUtils.isBlank(token)) {
            //封装请求参数
            ExtReqLog extReqLog = new ExtReqLog();
            extReqLog.setApiName("Monnify-Authentication");
            extReqLog.setReqUrl(monnifyConfig.getAuthenticationUrl());

            String base = "Basic " + Base64.getEncoder().encodeToString((monnifyConfig.getApikey() + ":" + monnifyConfig.getSecretKey()).getBytes());
            extReqLog.setReqParam("Authorization=" + base);
            Map<String, String> map = new HashMap<>();
            map.put("Authorization", base);
            extReqLog.setReqTime(DateUtils.dateTimeNow());


            //发送请求
            String s = "";
            try {
                s = HttpUtils.sendPost(monnifyConfig.getAuthenticationUrl(), "", map);
            } catch (Exception e) {
                log.error("monnifyAuthLogin:", e);
                extReqLog.setResTime(DateUtils.dateTimeNow());
                extReqLog.setCallStatus("2");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
            }

            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setRspResult(s);

            //解析请求结果
            if (s != null && !StringUtils.isBlank(s)) {

                JSONObject jsonObject = JSONObject.parseObject(s);
                String responseCode = jsonObject.getString("responseCode");
                String responseMessage = jsonObject.getString("responseMessage");

                extReqLog.setRetCode(responseCode);
                extReqLog.setRetMsg(responseMessage);

                if ("0".equals(responseCode)) {
                    JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));

                    String token1 = responseBody.getString("accessToken");
                    Integer expiresIn = responseBody.getInteger("expiresIn");

                    redisCache.setCacheObject(Constants.MONNIFY_AUTHENTICATION_ACCESSTOKEN, token1);
                    redisCache.expire(Constants.MONNIFY_AUTHENTICATION_ACCESSTOKEN, expiresIn - 10 * 60, TimeUnit.SECONDS);

                    //添加日志
                    extReqLog.setCallStatus("1");
                    extReqLogService.insertExtReqLog(extReqLog);

                    return token1;
                } else {
                    extReqLog.setCallStatus("0");
                    extReqLogService.insertExtReqLog(extReqLog);
                    throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
                }
            } else {
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);

            }
        }

        return token;
    }

    @Override
    public String monnifyTransactionsInitTransaction(String custNo, BigDecimal subtract, String orderSn, String desc, String[] methods) {

        //校验是否实名
        RealNameAuth realNameAuth = new RealNameAuth();
        realNameAuth.setCustNo(custNo);
        realNameAuth.setState("1");
        List<RealNameAuth> realNameAuths = iRealNameAuthService.selectRealNameAuthList(realNameAuth);
        if (realNameAuths != null && realNameAuths.size() > 0) {
            //封装请求参数
            String userId = getAppUserByCustNo(custNo).getUserUuid();

            ExtReqLog extReqLog = new ExtReqLog();
            extReqLog.setApiName("Init-Transaction");
            extReqLog.setReqUrl(monnifyConfig.getInitTransactionUrl());

            JSONObject json = new JSONObject();
            json.put("amount", subtract.doubleValue());
            json.put("customerName", realNameAuths.get(0).getFirstName() + " " + realNameAuths.get(0).getMiddleName() + " " + realNameAuths.get(0).getLastName());
            json.put("customerEmail", userId.substring(userId.length() - 10) + "@LCserver.com");
            json.put("paymentReference", orderSn);
            json.put("paymentDescription", desc);
            json.put("currencyCode", "NGN");
            json.put("contractCode", monnifyConfig.getContractCode());
            json.put("redirectUrl", "https://my-merchants-page.com/transaction/confirm");
            json.put("paymentMethods", methods);

            extReqLog.setReqParam(json.toString());
            extReqLog.setReqTime(DateUtils.dateTimeNow());

            Map<String, String> map = new HashMap<>();
            map.put("Authorization", "Basic " + Base64.getEncoder().encodeToString((monnifyConfig.getApikey() + ":" + monnifyConfig.getSecretKey()).getBytes()));

            //发送请求
            String s = "";
            try {
                s = HttpUtils.sendPost(monnifyConfig.getInitTransactionUrl(), json.toString(), map);
            } catch (Exception e) {
                log.error("monnifyTransactionsInitTransaction异常:", e);
                extReqLog.setResTime(DateUtils.dateTimeNow());
                extReqLog.setCallStatus("2");
                extReqLogService.insertExtReqLog(extReqLog);
                log.error(e + "");
                throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
            }

            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setRspResult(s);

            //解析请求结果
            if (s != null && !StringUtils.isBlank(s)) {

                JSONObject jsonObject = JSONObject.parseObject(s);
                String responseCode = jsonObject.getString("responseCode");
                String responseMessage = jsonObject.getString("responseMessage");

                extReqLog.setRetCode(responseCode);
                extReqLog.setRetMsg(responseMessage);

                if ("0".equals(responseCode)) {
                    extReqLog.setCallStatus("1");
                    extReqLogService.insertExtReqLog(extReqLog);

                    JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                    String transactionReference = responseBody.getString("transactionReference");
                    return transactionReference;
                } else {
                    extReqLog.setCallStatus("0");
                    extReqLogService.insertExtReqLog(extReqLog);
                    throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
                }
            } else {
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);

            }
        } else {
            throw new BusinessException("custNo=" + custNo, RspEnmu.CUST_IS_NULL_NEED_REALNAME_AUTH);
        }
    }

    @Override
    public String monnifyBankTransferInitPayment(String userId, String transactionReference, String accountDetailsBankCode) {

        //redisName
        String redisName = "monnify:Bank-Transfer-Init-Payment:" + userId + ":" + accountDetailsBankCode;

        //redis里有直接返回
        String ussdPaymentRedis = redisCache.getCacheObject(redisName);
        if (ussdPaymentRedis != null && !StringUtils.isBlank(ussdPaymentRedis)) {
            return ussdPaymentRedis;
        }

        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("Bank-Transfer-Init-Payment");
        extReqLog.setReqUrl(monnifyConfig.getBankTransferInitPaymentUrl());

        JSONObject json = new JSONObject();
        json.put("transactionReference", transactionReference);
        json.put("bankCode", accountDetailsBankCode);

        extReqLog.setReqParam(json.toString());
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> map = new HashMap<>();
        map.put("Authorization", "Basic " + Base64.getEncoder().encodeToString((monnifyConfig.getApikey() + ":" + monnifyConfig.getSecretKey()).getBytes()));

        //发送请求
        String s = "";
        try {
            s = HttpUtils.sendPost(monnifyConfig.getBankTransferInitPaymentUrl(), json.toString(), map);
        } catch (Exception e) {
            log.error("monnifyBankTransferInitPayment 异常:", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(s);

        //解析请求结果
        if (s != null && !StringUtils.isBlank(s)) {

            JSONObject jsonObject = JSONObject.parseObject(s);
            String responseCode = jsonObject.getString("responseCode");
            String responseMessage = jsonObject.getString("responseMessage");

            extReqLog.setRetCode(responseCode);
            extReqLog.setRetMsg(responseMessage);

            if ("0".equals(responseCode)) {
                extReqLog.setCallStatus("1");
                extReqLogService.insertExtReqLog(extReqLog);

                JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                String ussdPayment = responseBody.getString("ussdPayment");

                //存redis
                redisCache.setCacheObject(redisName, ussdPayment);
                redisCache.expire(redisName, responseBody.getInteger("accountDurationSeconds"), TimeUnit.SECONDS);

                return ussdPayment;
            } else {
                //接口异常
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
            }
        } else {
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }
    }

    @Override
    public JSONObject monnifyGetTransactionStatus(String transactionReference) {
        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("Get-Transaction-Status");

        try {
            transactionReference = URLEncoder.encode(transactionReference, "UTF-8").replace("+", "%20");
        } catch (Exception e) {
            throw new BusinessException("", RspEnmu.SYSTEM_ERR);
        }

        extReqLog.setReqUrl(monnifyConfig.getGetTransactionStatus() + transactionReference);

        extReqLog.setReqParam(transactionReference);
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> map = new HashMap<>();
        map.put("Authorization", "Bearer " + monnifyAuthLogin());

        //发送请求
        String s = "";
        try {
            s = HttpUtils.sendGet(monnifyConfig.getGetTransactionStatus() + transactionReference, "", Constants.UTF8, map);
        } catch (Exception e) {
            log.error("monnifyGetTransactionStatus 异常:", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(s);

        //解析请求结果
        if (s != null && !StringUtils.isBlank(s)) {

            JSONObject jsonObject = JSONObject.parseObject(s);
            String responseCode = jsonObject.getString("responseCode");
            String responseMessage = jsonObject.getString("responseMessage");

            extReqLog.setRetCode(responseCode);
            extReqLog.setRetMsg(responseMessage);

            if ("0".equals(responseCode)) {
                extReqLog.setCallStatus("1");
                extReqLogService.insertExtReqLog(extReqLog);

                JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                //String paymentStatus = responseBody.getString("paymentStatus");
                return responseBody;
            } else {
                //接口异常
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
            }
        } else {
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }
    }

    @Override
    public JSONObject callMonnifyService(JSONObject paramJson, String reqUrl, String apiName, boolean isPost) {
        log.info("callMonnifyService 参数: {}, reqUrl: {}, apiName: {}" + paramJson.toJSONString(), reqUrl, apiName);

        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName(apiName);
        extReqLog.setReqUrl(reqUrl);
        extReqLog.setReqParam(paramJson.toString());
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> head = new HashMap<>();
        head.put("Content-Type", "application/json");
        head.put("Authorization", "Bearer " + monnifyAuthLogin());

        //发送请求
        String rsp = "";
        try {
            if (extApiMock()) {
                rsp = payStackApiMockData(apiName).toJSONString();
                log.info("外部接口 {} 返回模拟报文：{}", apiName, rsp);
            } else {
                if (isPost) {
                    rsp = HttpUtils.sendPost(reqUrl, paramJson.toString(), head);
                } else {
                    rsp = HttpUtils.sendGet(reqUrl, "", "UTF-8", head);
                }

            }
        } catch (Exception e) {
            log.error("Call {} error:", apiName, e);

            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLog.setRspResult(e.getMessage());
            extReqLogService.insertExtReqLog(extReqLog);

            if ("timeout".equals(e.getMessage())) {
                throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
            }
            throw new BusinessException(e.getMessage(), RspEnmu.EXT_API_ERR);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(rsp);

        //解析请求结果
        if (StringUtils.isBlank(rsp)) {
            log.error("{} 返回结果为空", apiName);
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }

        JSONObject jsonObject = JSONObject.parseObject(rsp);
        String responseCode = jsonObject.getString("responseCode");
        String responseMessage = jsonObject.getString("responseMessage");

        extReqLog.setRetCode(responseCode);
        extReqLog.setRetMsg(responseMessage);

        if (!"0".equals(responseCode)) {
            //接口返回失败
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);

            if ("You can not reserve two accounts with the same reference".equals(responseMessage)) {
                throw new BusinessException(responseMessage, RspEnmu.MONNIFY_RESERVED_IS_EXISTS);
            }

            if ("Cannot find reserved account".equals(responseMessage)) {
                throw new BusinessException(responseMessage, RspEnmu.MONNIFY_RESERVED_IS_NOT_EXISTS);
            }

            if (responseMessage.contains("We do not support virtual accounts from bank")) {
                throw new BusinessException(responseMessage, RspEnmu.MONNIFY_RESERVED_DO_NOT_SUPPORT);
            }

            throw new BusinessException(responseMessage, rsp, RspEnmu.MONNIFY_INTERFACE_FALSE);
        }

        extReqLog.setCallStatus("1");
        extReqLogService.insertExtReqLog(extReqLog);
        return JSONObject.parseObject(jsonObject.getString("responseBody"));
    }

    @Override
    public JSONObject monnifyBankTransferReservedAccounts(String accountName, String bvn, String custEmail, String custName, String custNo) {

        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("Bank-Transfer-Reserved-Accounts");

        JSONObject json = new JSONObject();
        json.put("accountReference", custNo);
        json.put("accountName", accountName);
        json.put("currencyCode", "NGN");
        json.put("contractCode", monnifyConfig.getContractCode());
        json.put("customerEmail", custEmail);
        json.put("bvn", bvn);
        json.put("customerName", custName);
        json.put("getAllAvailableBanks", false);
        json.put("preferredBanks", new String[]{monnifyConfig.getBankCard()});
        log.info("monnifyConfig{}========{}", JSONObject.toJSONString(monnifyConfig), accountName);

        extReqLog.setReqUrl(monnifyConfig.getBankTransferReservedAccounts());

        extReqLog.setReqParam(json.toString());
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> map = new HashMap<>();
        map.put("Content-Type", "application/json");
        map.put("Authorization", "Bearer " + monnifyAuthLogin());

        //发送请求
        String s = "";
        try {
            s = HttpUtils.sendPost(monnifyConfig.getBankTransferReservedAccounts(), json.toString(), map);
        } catch (Exception e) {
            log.error("monnifyBankTransferReservedAccounts 异常:", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);

            if ("timeout".equals(e.getMessage())) {
                throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
            }
            throw new BusinessException(e.getMessage(), RspEnmu.EXT_API_ERR);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(s);

        //解析请求结果
        if (s != null && !StringUtils.isBlank(s)) {

            JSONObject jsonObject = JSONObject.parseObject(s);
            String responseCode = jsonObject.getString("responseCode");
            String responseMessage = jsonObject.getString("responseMessage");

            extReqLog.setRetCode(responseCode);
            extReqLog.setRetMsg(responseMessage);

            if ("0".equals(responseCode)) {
                extReqLog.setCallStatus("1");
                extReqLogService.insertExtReqLog(extReqLog);

                JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                //String paymentStatus = responseBody.getString("paymentStatus");
                return responseBody;
            } else {

                //接口异常
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
//                if (responseMessage.equals("You can not reserve two accounts with the same reference")) {
//                    JSONObject jsonObject1 = monnifyGetBankTransferReservedAccounts(custNo, token);
//                    return jsonObject1;
//                }
                throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
            }
        } else {
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }
    }

    @Override
    public JSONObject monnifyGetBankTransferReservedAccounts(String custNo) {
        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("Get-Bank-Transfer-Reserved-Accounts");
        extReqLog.setReqUrl(monnifyConfig.getGetBankTransferReservedAccounts() + custNo);

        extReqLog.setReqParam(custNo);
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> map = new HashMap<>();
        map.put("Authorization", "Bearer " + monnifyAuthLogin());

        //发送请求
        String s = "";
        try {
            s = HttpUtils.sendGet(monnifyConfig.getGetBankTransferReservedAccounts() + custNo, "", Constants.UTF8, map);
        } catch (Exception e) {
            log.error("monnifyGetBankTransferReservedAccounts 异常:", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(s);

        //解析请求结果
        if (s != null && !StringUtils.isBlank(s)) {

            JSONObject jsonObject = JSONObject.parseObject(s);
            String responseCode = jsonObject.getString("responseCode");
            String responseMessage = jsonObject.getString("responseMessage");

            extReqLog.setRetCode(responseCode);
            extReqLog.setRetMsg(responseMessage);

            if ("0".equals(responseCode)) {
                extReqLog.setCallStatus("1");
                extReqLogService.insertExtReqLog(extReqLog);

                //JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                //String paymentStatus = responseBody.getString("paymentStatus");
                return jsonObject;
            } else {
                //接口异常
                // {"requestSuccessful":false,"responseMessage":"Cannot find reserved account","responseCode":"99"}
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                return jsonObject;
                // throw new BusinessException(responseMessage, RspEnmu.MONNIFY_GET_BANK_TRANSFER_RESERVED_ACCOUNTS);
            }
        } else {
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }
    }

    @Override
    public JSONObject monnifyGetAllTransactionsOnReservedAccount(String accountReference, Integer page, Integer size) {
        //封装请求参数
        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName("Get-All-Transactions-On-Reserved-Account");

        extReqLog.setReqUrl(monnifyConfig.getGetAllTransactionsOnReservedAccountUrl());

        String param = "accountReference=" + accountReference + "&page=" + page + "&size=" + size;

        extReqLog.setReqParam(param);
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        Map<String, String> map = new HashMap<>();
        map.put("Authorization", "Bearer " + monnifyAuthLogin());

        //发送请求
        String s = "";
        try {
            s = HttpUtils.sendGet(monnifyConfig.getGetAllTransactionsOnReservedAccountUrl(), param, Constants.UTF8, map);
        } catch (Exception e) {
            log.error("monnifyGetAllTransactionsOnReservedAccount 异常:", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
        }

        extReqLog.setResTime(DateUtils.dateTimeNow());
        extReqLog.setRspResult(s);

        //解析请求结果
        if (s != null && !StringUtils.isBlank(s)) {

            JSONObject jsonObject = JSONObject.parseObject(s);
            String responseCode = jsonObject.getString("responseCode");
            String responseMessage = jsonObject.getString("responseMessage");

            extReqLog.setRetCode(responseCode);
            extReqLog.setRetMsg(responseMessage);

            if ("0".equals(responseCode)) {
                extReqLog.setCallStatus("1");
                extReqLogService.insertExtReqLog(extReqLog);

                JSONObject responseBody = JSONObject.parseObject(jsonObject.getString("responseBody"));
                //String paymentStatus = responseBody.getString("paymentStatus");
                return responseBody;
            } else {
                //接口异常
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(responseMessage, s, RspEnmu.MONNIFY_INTERFACE_ERROR);
            }
        } else {
            //接口异常
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.MONNIFY_INTERFACE_ERROR);
        }
    }

    @Override
    public String ruleRequest(JSONObject riskParam, String url, String apiName) {

        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName(apiName);
        extReqLog.setReqUrl(url);
        extReqLog.setReqParam(riskParam.toString());
        extReqLog.setReqTime(DateUtils.dateTimeNow());

        String apiResult;
        try {
            String content = TDAESUtil.Encrypt(riskParam.toJSONString(), ruleConfig.getAesKey());
            // log.info("规则加密后content:{}", content);

            RequestBody requestBody = new FormBody.Builder().add("content", content).build();
            Request request = new Request.Builder().url(url).method("POST", requestBody)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
                    .build();

//            //OkHttpClient client = new OkHttpClient().newBuilder().build().callTimeoutMillis();
//            OkHttpClient client = new OkHttpClient().newBuilder()
//                    //设置连接超时时间
//                    .connectTimeout(120, TimeUnit.SECONDS)
//                    //设置读取超时时间
//                    .readTimeout(120, TimeUnit.SECONDS)
//                    .build();
//            Response response = client.newCall(request).execute();

            // wqg修改2022.01月19，加入链接池
            Response response = okHttpClient.newCall(request).execute();


            extReqLog.setRetCode(response.code() + "");
            extReqLog.setRetMsg(response.message());

            if (200 != response.code()) {
                extReqLog.setCallStatus("0");
                extReqLogService.insertExtReqLog(extReqLog);
                throw new BusinessException(RspEnmu.TD_CALL_ERROR);
            }
            apiResult = response.body().string();
            log.info("规则调用接口返回：{}", apiResult);

            apiResult = TDAESUtil.Decrypt(apiResult, ruleConfig.getAesKey());
            log.info("规则返回结果解密：{} ", apiResult);

            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setRspResult(apiResult);
            extReqLog.setCallStatus("1");
            extReqLogService.insertExtReqLog(extReqLog);
        } catch (Exception e) {
            log.error("规则-调用异常", e);
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setCallStatus("2");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(e.getMessage(), RspEnmu.TD_CALL_ERROR);
        }
        if (StringUtils.isBlank(apiResult)) {
            extReqLog.setCallStatus("0");
            extReqLogService.insertExtReqLog(extReqLog);
            throw new BusinessException(NULL_DAYA, RspEnmu.TD_CALL_ERROR);
        }

        return apiResult;
    }

    @Override
    public JSONObject invokePayStackApi(String apiName, String apiUrl, String reqMethod, JSONObject reqParam, String userId) {
        log.info("外部接口 {} 调用：apiUrl = {}, reqParam = {}", apiName, apiUrl, reqParam);

        JSONObject apiRes = null;

        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName(apiName);
        extReqLog.setReqUrl(apiUrl);
        extReqLog.setReqTime(DateUtils.dateTimeNow());
        extReqLog.setUserId(userId);

        try {
            boolean flag = false;
            String secretKey = payStackConfig.getSecretKey();
            if (StringUtils.equalsAny(apiName, "NUBAN-Identity-Verification", "Bank-Coverage", "NUBAN-Identity-Verification-back", "Okra-bvn-verify")) {
                secretKey = okraConfig.getPrivateKey();
                flag = true;
            }

            Request request = null;
            if ("GET".equals(reqMethod)) {
                request = new Request.Builder()
                        .url(apiUrl)
                        .method(reqMethod, null)
                        .addHeader("Authorization", "Bearer " + secretKey)
                        .build();
                if (flag) {
                    extReqLog.setReqParam(reqParam == null ? "" : reqParam.getString("nuban"));
                } else {
                    extReqLog.setReqParam(apiUrl.substring(apiUrl.lastIndexOf("/") + 1));
                }
            } else {
                extReqLog.setReqParam(reqParam.toJSONString());

                MediaType mediaType = MediaType.parse("application/json");
                RequestBody body = RequestBody.create(mediaType, reqParam.toJSONString());
                request = new Request.Builder()
                        .url(apiUrl)
                        .method(reqMethod, body)
                        .addHeader("Authorization", "Bearer " + secretKey)
                        .addHeader("Content-Type", "application/json")
                        .build();
            }

            if (extApiMock()) {
                apiRes = payStackApiMockData(apiName);
                log.info("外部接口 {} 返回模拟报文：{}", apiName, apiRes);
            } else {
                // Response response = client.newCall(request).execute();

                // wqg修改2022.01月19，加入链接池
                Response response = okHttpClient.newCall(request).execute();

                String res = response.body().string(); //{"message": "Endpoint request timed out"}
                log.info("外部接口 {} 返回报文：{}", apiName, res);

                if (res.contains("<head>")) {
                    throw new BusinessException(res, RspEnmu.NETWORK_BUSY);
                }
                apiRes = JSON.parseObject(res);
            }

            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLog.setRspResult(apiRes == null ? "" : apiRes.toJSONString());

            if (apiRes == null) {
                throw new BusinessException(RspEnmu.EXTERNAL_API_RSP_NULL);
            }

            String status = apiRes.getString("status");
            String message = apiRes.getString("message");

            if (flag && !Func.hasEmpty(apiRes.get("message"), apiRes.get("data"))) {
                // {"status":"error","message":"Error validation Identity, please try again!!","data":null}
                // {"data":{"msg":"Error validation Identity, please try again!!","success":false,"status":"error"},"message":"Error validation Identity, please try again!!","status":"success"}

                if (apiRes.getString("message").contains("Error") && apiRes.get("data") != null && apiRes.getJSONObject("data").size() > 0) {
                    status = apiRes.getJSONObject("data").getString("status");
                    message = apiRes.getJSONObject("data").getString("msg");
                }
            }

            extReqLog.setCallStatus(status);
            extReqLog.setRetMsg(message);

            // {"message":"You cannot initiate third party payouts at this time","status":false}
            // NUBAN-Identity-Verification 返回报文：{"data":{"msg":"Error validation Identity, please try again!!","success":false,"status":"error"},"message":"Error validation Identity, please try again!!","status":"success"}
            if ((!flag && !Boolean.parseBoolean(status)) || (flag && StringUtils.equals(status, "error")) || (flag && StringUtils.equals(status, "404"))) {
                log.info("{} 接口返回结果为：status = {}，message = {}", apiName, status, message);

                if (StringUtils.equals("Verify-Transaction", apiName)) {
                    if (message.contains("not found") || "Transfer not found".equals(message)) {
                        throw new BusinessException(message, RspEnmu.TRANSACTION_SERIAL_NO_NOT_EXISTS);
                    }
                    if (message.contains("already exists") || message.equals("Please provide a unique reference. Reference already exists on a transfer")) {
                        throw new BusinessException(message, RspEnmu.REFERENCE_ALREADY_EXISTS_ON_TRANSFER);
                    }
                }

                if (StringUtils.equals("Verify-Transfer", apiName)) {
                    if (message.contains("not found") || "Transfer not found".equals(message)) {
                        throw new BusinessException(message, RspEnmu.TRANSACTION_SERIAL_NO_NOT_EXISTS);
                    }
                    if (message.contains("already exists") || message.equals("Please provide a unique reference. Reference already exists on a transfer")) {
                        throw new BusinessException(message, RspEnmu.REFERENCE_ALREADY_EXISTS_ON_TRANSFER);
                    }
                }

                //代扣
                if (StringUtils.equals("Charge-Authorization", apiName)) {

                    String withhold_change_card_msg = iSysConfigService.selectConfigByKey("withhold_change_card_msg");
                    String[] withholdChangeCardMsgs = withhold_change_card_msg.substring(2, withhold_change_card_msg.length() - 2).split("\",\"");

                    //Charge attempt cannot be fulfilled until
                    if (withholdChangeCardMsgs.length == 1 && message.contains(withholdChangeCardMsgs[0])
                            || withholdChangeCardMsgs.length > 1 && StringUtils.containsAny(message, withholdChangeCardMsgs)) {
                        throw new BusinessException(message, RspEnmu.WITHHOLD_CHANGE_CARD);
                    }
                }
                if (StringUtils.equalsAny(message,
                        "Bank code is required",
                        "Please wait a few seconds and try again","Endpoint request timed out","Error Occurred")) {
                    throw new BusinessException(message, RspEnmu.NETWORK_BUSY);
                }

                // Initiate-Transfer 放款
                if (StringUtils.equals("Initiate-Transfer", apiName)) {
                    if (StringUtils.equalsAny(message,
                            "Your balance is not enough to fulfil this request",
                            "You cannot initiate third party payouts at this time"
                    )) {
                        throw new BusinessException(message, RspEnmu.INSUFFICIENT_WALLET_BALANCE);
                    }
                    // message=/时，修改loanOrder订单状态为放款失败(loan_status=5)，触发短信提醒提醒失败因收款帐户不可用；
                    if (StringUtils.equalsAny(message,
                            "Cannot resolve account",
                            "Account number is invalid"
                    )) {
                        throw new BusinessException(message, RspEnmu.ACCOUNT_NUMBER_IS_INVALID);
                    }
                    if (message.equals("Please provide a unique reference. Reference already exists on a transfer")) {
                        throw new BusinessException(message, RspEnmu.REFERENCE_ALREADY_EXISTS_ON_TRANSFER);
                    }
                }
                // 此处不抛出异常全部返回
                if (StringUtils.containsAny(apiName,
                        "Paystack-Validate-Customer",
                        "Paystack-Create-Customer", "Paystack-create-va")) {
                    return apiRes;
                }
                throw new BusinessException(message, RspEnmu.EXTERNAL_API_RSP_FALSE);
            }

            extReqLog.setState("1");

            if (StringUtils.equals(apiName, "Bank-Coverage")) {
                JSONArray jsonArray = apiRes.getJSONObject("data").getJSONArray("banks");
                Iterator it = jsonArray.stream().iterator();
                while (it.hasNext()) {
                    JSONObject json = ((JSONObject) it.next());
                    json.put("v2_icon", "");
                    json.put("v2_logo", "");
                }
                apiRes.getJSONObject("data").put("banks", jsonArray);
                extReqLog.setRspResult(apiRes.toJSONString());
            }
        } catch (ConnectException | SocketTimeoutException | SSLException | StreamResetException e) {
            log.error("{} 接口请求异常", apiName, e);
            extReqLog.setRemark(e.getMessage());
            extReqLog.setState("2");
            extReqLog.setCallStatus("0");
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
        } catch (Exception e) {
            extReqLog.setRemark(e.getMessage());
            extReqLog.setCallStatus("0");

            if (e instanceof BusinessException) {
                extReqLog.setState("0");
                throw (BusinessException) e;
            }

            extReqLog.setState("2");
            log.error("{} 接口处理异常", apiName, e);

            if ("timeout".equals(e.getMessage())) {
                throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_BUSY);
            }
            throw new BusinessException(e.getMessage(), RspEnmu.EXT_API_ERR);

        } finally {
            extReqLogService.insertExtReqLog(extReqLog);
        }

        // 需要返回全部信息的
        if (StringUtils.containsAny(apiName,
                "List-Banks","Check-Balance", "Paystack-Partial-Debits")) {
            return apiRes;
        }

        return apiRes.getJSONObject("data");
    }

    private Integer insertExtReqLog(ExtReqLog extReqLog, String status) {
        extReqLog.setState(status);
        return extReqLogService.insertExtReqLog(extReqLog);
    }

    @Override
    public JSONObject crsRequest(OkRequestVo okRequestVo) {

        ExtReqLog extReqLog = new ExtReqLog();
        extReqLog.setApiName(okRequestVo.getApiName());
        extReqLog.setReqUrl(okRequestVo.getUrl());
        extReqLog.setReqParam(okRequestVo.getParams().toString());
        extReqLog.setReqTime(DateUtils.dateTimeNow());
        extReqLog.setUserId(okRequestVo.getUserId());

        String apiResult = "";
        try {
            //http请求
            Response response = okHttpCrsRequest(okRequestVo);
            log.info("调用接口返回：{}", response.toString());
            extReqLog.setRetCode(response.code() + "");
            extReqLog.setRetMsg(response.message());

            apiResult = response.body().string();
            extReqLog.setRspResult(apiResult);

            if (404 == response.code()) {
                extReqLog.setCallStatus("0");
                return JSONObject.parseObject(apiResult);
            }

            if (200 != response.code()) {
                extReqLog.setCallStatus("0");
                throw new BusinessException(response.message(), RspEnmu.NETWORK_EXCEPTION.getCode());
            }
            extReqLog.setCallStatus("1");

        } catch (Exception e) {
            log.error("调用接口异常", e);
            extReqLog.setCallStatus("2");
            throw new BusinessException(e.getMessage(), RspEnmu.NETWORK_EXCEPTION);
        } finally {
            extReqLog.setResTime(DateUtils.dateTimeNow());
            extReqLogService.insertExtReqLog(extReqLog);
        }
        return JSONObject.parseObject(apiResult);
    }

    /**
     * 用于创建VA 不适用其他功能
     *
     * @param apiName
     * @param apiUrl
     * @param type
     * @param reqParam
     * @return
     */
    @Override
    @Retryable(value = BusinessException.class, recover = "recoverDelPaystackForVa", maxAttempts = 1, backoff = @Backoff(delay = 500, multiplier = 2))
    public JSONObject delPaystackForVa(String apiName, String apiUrl, String type, JSONObject reqParam, String custNo) {
        return invokePayStackApi(apiName, apiUrl, type, reqParam, null);
    }

    /**
     * 重试3次 都失败无回调
     *
     * @param apiName
     * @param apiUrl
     * @param type
     * @param reqParam
     * @return
     */
    @Override
    @Retryable(value = BusinessException.class, recover = "retryRecoverdelPaystackForVaRetry", maxAttempts = 1, backoff = @Backoff(delay = 500, multiplier = 2))
    public JSONObject delPaystackForVaRetry(String apiName, String apiUrl, String type, JSONObject reqParam) {
        return invokePayStackApi(apiName, apiUrl, type, reqParam, null);
    }

    @Override
    public JSONObject dealPaystackForCardWithhold(String apiName, String apiUrl, String type, JSONObject reqParam) {
        return invokePayStackApi(apiName, apiUrl, type, reqParam, null);
    }

    @Recover
    public JSONObject retryRecoverdelPaystackForVaRetry(BusinessException e, String apiName, String apiUrl, String type, JSONObject reqParam) {
        JSONObject res = new JSONObject();
        res.put("status", false);
        return res;
    }

    @Recover
    public JSONObject recoverDelPaystackForVa(BusinessException e, String apiName, String apiUrl, String type, JSONObject reqParam, String custNo) {
        JSONObject res = new JSONObject();
        res.put("status", false);
        log.info("重试几次都失败，最后回调，{},{}", apiName, reqParam);
        createExtTryQueue(apiName, apiUrl, type, reqParam, custNo);
        return res;
    }

    /**
     * 进入队列数据库，后面每半个小时轮询一次
     *
     * @param apiName
     * @param apiUrl
     * @param type
     * @param reqParam
     */
    private void createExtTryQueue(String apiName, String apiUrl, String type, JSONObject reqParam, String custNo) {
        // reqParam  记录apiName apiUrl 后续根据表的 TryType 和 apiName进行走什么处理接口
        reqParam.put("apiName", apiName);
        reqParam.put("apiUrl", apiUrl);
        ExtTryQueue extTryQueue = new ExtTryQueue();
        extTryQueue.setCustNo(custNo);
        extTryQueue.setTryCount(3L);
        extTryQueue.setTryType(ExtTryQueue.TYPE_PAYSTACK_CREATE_VA);
        extTryQueue.setParamData(reqParam.toJSONString());
        extTryQueue.setState("0");
        extTryQueueMapper.insert(extTryQueue);
    }

    private Response okHttpCrsRequest(OkRequestVo okRequestVo) {

        RequestBody body = null;
        if (Func.isNotEmpty(okRequestVo.getReqEnum())) {
            MediaType mediaType = MediaType.parse(okRequestVo.getReqEnum().getType());
            body = RequestBody.create(mediaType, okRequestVo.getParams().toString());
        }

        Request request = new Request.Builder()
                .url(okRequestVo.getUrl())
                .method(okRequestVo.getReqMethod(), "GET".equalsIgnoreCase(okRequestVo.getReqMethod()) ? null : body)
                .headers(okRequestVo.getHeaders())
                .build();
        // 链接池使用
//        OkHttpClient client = new OkHttpClient().newBuilder()
//                //设置连接超时时间
//                .connectTimeout(160, TimeUnit.SECONDS)
//                //设置读取超时时间
//                .readTimeout(160, TimeUnit.SECONDS)
//                .build();

        int reentryNum = 3;
        Response execute = null;
        while (reentryNum > 0) {
            try {
                execute = okHttpClient.newCall(request).execute();
                reentryNum = 0;
            } catch (SocketTimeoutException e) {
                reentryNum--;
                log.error("{}请求超时，还剩{}次", okRequestVo.getApiName(), reentryNum);
            } catch (Exception e) {
                reentryNum--;
                log.error("{}请求超时，还剩{}次", okRequestVo.getApiName(), reentryNum);
            }
        }

        if (execute == null) {
            throw new BusinessException(RspEnmu.NETWORK_EXCEPTION);
        }
        return execute;
    }

    private JSONObject payStackApiMockData(String apiName) throws IOException {
        String apiRes = apiRes = iSysConfigService.selectConfigByKey(apiName);

//        switch (apiName) {
//            case "Initialize-Transaction":
//                // apiRes = "{\"status\":true,\"message\":\"Authorization URL created\",\"data\":{\"authorization_url\":\"https://checkout.paystack.com/0peioxfhpn\",\"access_code\":\"0peioxfhpn\",\"reference\":\"7PVGX8MEk85tgeEpVDtD\"}}";
////                Response response = client.newCall(request).execute();
////                apiRes = response.body().string().toString();
//                apiRes = iSysConfigService.selectConfigByKey("Initialize-Transaction");
//                log.info("外部接口 {} 返回报文：{}", apiName, apiRes);
//                break;
//            case "List-Banks":
//                apiRes = "{\"status\":true,\"message\":\"Banks retrieved\",\"data\":[{\"name\":\"Abbey Mortgage Bank\",\"slug\":\"abbey-mortgage-bank\",\"code\":\"801\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":174,\"createdAt\":\"2020-12-07T16:19:09.000Z\",\"updatedAt\":\"2020-12-07T16:19:19.000Z\"},{\"name\":\"Access Bank\",\"slug\":\"access-bank\",\"code\":\"044\",\"longcode\":\"044150149\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":1,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T08:06:44.000Z\"},{\"name\":\"Access Bank (Diamond)\",\"slug\":\"access-bank-diamond\",\"code\":\"063\",\"longcode\":\"063150162\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":3,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T08:06:48.000Z\"},{\"name\":\"ALAT by WEMA\",\"slug\":\"alat-by-wema\",\"code\":\"035A\",\"longcode\":\"035150103\",\"gateway\":\"emandate\",\"pay_with_bank\":true,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":27,\"createdAt\":\"2017-11-15T12:21:31.000Z\",\"updatedAt\":\"2021-02-18T14:55:34.000Z\"},{\"name\":\"ASO Savings and Loans\",\"slug\":\"asosavings\",\"code\":\"401\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":63,\"createdAt\":\"2018-09-23T05:52:38.000Z\",\"updatedAt\":\"2019-01-30T09:38:57.000Z\"},{\"name\":\"Bowen Microfinance Bank\",\"slug\":\"bowen-microfinance-bank\",\"code\":\"50931\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":108,\"createdAt\":\"2020-02-11T15:38:57.000Z\",\"updatedAt\":\"2020-02-11T15:38:57.000Z\"},{\"name\":\"CEMCS Microfinance Bank\",\"slug\":\"cemcs-microfinance-bank\",\"code\":\"50823\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":74,\"createdAt\":\"2020-03-23T15:06:13.000Z\",\"updatedAt\":\"2020-03-23T15:06:28.000Z\"},{\"name\":\"Citibank Nigeria\",\"slug\":\"citibank-nigeria\",\"code\":\"023\",\"longcode\":\"023150005\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":2,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:24:02.000Z\"},{\"name\":\"Coronation Merchant Bank\",\"slug\":\"coronation-merchant-bank\",\"code\":\"559\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":173,\"createdAt\":\"2020-11-24T10:25:07.000Z\",\"updatedAt\":\"2020-11-24T10:25:07.000Z\"},{\"name\":\"Ecobank Nigeria\",\"slug\":\"ecobank-nigeria\",\"code\":\"050\",\"longcode\":\"050150010\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":4,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:23:53.000Z\"},{\"name\":\"Ekondo Microfinance Bank\",\"slug\":\"ekondo-microfinance-bank\",\"code\":\"562\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":64,\"createdAt\":\"2018-09-23T05:55:06.000Z\",\"updatedAt\":\"2018-09-23T05:55:06.000Z\"},{\"name\":\"Eyowo\",\"slug\":\"eyowo\",\"code\":\"50126\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":167,\"createdAt\":\"2020-09-07T13:52:22.000Z\",\"updatedAt\":\"2020-11-24T10:03:21.000Z\"},{\"name\":\"Fidelity Bank\",\"slug\":\"fidelity-bank\",\"code\":\"070\",\"longcode\":\"070150003\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":6,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T07:25:19.000Z\"},{\"name\":\"First Bank of Nigeria\",\"slug\":\"first-bank-of-nigeria\",\"code\":\"011\",\"longcode\":\"011151003\",\"gateway\":\"ibank\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":7,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2021-03-25T14:22:52.000Z\"},{\"name\":\"First City Monument Bank\",\"slug\":\"first-city-monument-bank\",\"code\":\"214\",\"longcode\":\"214150018\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":8,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T08:06:46.000Z\"},{\"name\":\"FSDH Merchant Bank Limited\",\"slug\":\"fsdh-merchant-bank-limited\",\"code\":\"501\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":112,\"createdAt\":\"2020-08-20T09:37:04.000Z\",\"updatedAt\":\"2020-11-24T10:03:22.000Z\"},{\"name\":\"Globus Bank\",\"slug\":\"globus-bank\",\"code\":\"00103\",\"longcode\":\"103015001\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":70,\"createdAt\":\"2020-02-11T15:38:57.000Z\",\"updatedAt\":\"2020-02-11T15:38:57.000Z\"},{\"name\":\"Guaranty Trust Bank\",\"slug\":\"guaranty-trust-bank\",\"code\":\"058\",\"longcode\":\"058152036\",\"gateway\":\"ibank\",\"pay_with_bank\":true,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":9,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2021-01-01T11:22:11.000Z\"},{\"name\":\"Hackman Microfinance Bank\",\"slug\":\"hackman-microfinance-bank\",\"code\":\"51251\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":111,\"createdAt\":\"2020-08-20T09:32:48.000Z\",\"updatedAt\":\"2020-11-24T10:03:24.000Z\"},{\"name\":\"Hasal Microfinance Bank\",\"slug\":\"hasal-microfinance-bank\",\"code\":\"50383\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":81,\"createdAt\":\"2020-02-11T15:38:57.000Z\",\"updatedAt\":\"2020-02-11T15:38:57.000Z\"},{\"name\":\"Heritage Bank\",\"slug\":\"heritage-bank\",\"code\":\"030\",\"longcode\":\"030159992\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":10,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:24:23.000Z\"},{\"name\":\"Ibile Microfinance Bank\",\"slug\":\"ibile-mfb\",\"code\":\"51244\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":168,\"createdAt\":\"2020-10-21T10:54:20.000Z\",\"updatedAt\":\"2020-10-21T10:54:33.000Z\"},{\"name\":\"Infinity MFB\",\"slug\":\"infinity-mfb\",\"code\":\"50457\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":172,\"createdAt\":\"2020-11-24T10:23:37.000Z\",\"updatedAt\":\"2020-11-24T10:23:37.000Z\"},{\"name\":\"Jaiz Bank\",\"slug\":\"jaiz-bank\",\"code\":\"301\",\"longcode\":\"301080020\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":22,\"createdAt\":\"2016-10-10T17:26:29.000Z\",\"updatedAt\":\"2016-10-10T17:26:29.000Z\"},{\"name\":\"Keystone Bank\",\"slug\":\"keystone-bank\",\"code\":\"082\",\"longcode\":\"082150017\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":11,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:23:45.000Z\"},{\"name\":\"Kuda Bank\",\"slug\":\"kuda-bank\",\"code\":\"50211\",\"longcode\":\"\",\"gateway\":\"digitalbankmandate\",\"pay_with_bank\":true,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":67,\"createdAt\":\"2019-11-15T17:06:54.000Z\",\"updatedAt\":\"2020-07-01T15:05:18.000Z\"},{\"name\":\"Lagos Building Investment Company Plc.\",\"slug\":\"lbic-plc\",\"code\":\"90052\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":109,\"createdAt\":\"2020-08-10T15:07:44.000Z\",\"updatedAt\":\"2020-08-10T15:07:44.000Z\"},{\"name\":\"Mayfair MFB\",\"slug\":\"mayfair-mfb\",\"code\":\"50563\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":175,\"createdAt\":\"2021-02-02T08:28:38.000Z\",\"updatedAt\":\"2021-02-02T08:28:38.000Z\"},{\"name\":\"One Finance\",\"slug\":\"one-finance\",\"code\":\"565\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":82,\"createdAt\":\"2020-06-16T08:15:31.000Z\",\"updatedAt\":\"2020-06-16T08:15:31.000Z\"},{\"name\":\"PalmPay\",\"slug\":\"palmpay\",\"code\":\"999991\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":169,\"createdAt\":\"2020-11-24T09:58:37.000Z\",\"updatedAt\":\"2020-11-24T10:03:19.000Z\"},{\"name\":\"Parallex Bank\",\"slug\":\"parallex-bank\",\"code\":\"526\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":26,\"createdAt\":\"2017-03-31T13:54:29.000Z\",\"updatedAt\":\"2019-01-30T09:43:56.000Z\"},{\"name\":\"Parkway - ReadyCash\",\"slug\":\"parkway-ready-cash\",\"code\":\"311\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":110,\"createdAt\":\"2020-08-10T15:07:44.000Z\",\"updatedAt\":\"2020-08-10T15:07:44.000Z\"},{\"name\":\"Paycom\",\"slug\":\"paycom\",\"code\":\"999992\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":171,\"createdAt\":\"2020-11-24T10:20:45.000Z\",\"updatedAt\":\"2020-11-24T10:20:54.000Z\"},{\"name\":\"Petra Mircofinance Bank Plc\",\"slug\":\"petra-microfinance-bank-plc\",\"code\":\"50746\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":170,\"createdAt\":\"2020-11-24T10:03:06.000Z\",\"updatedAt\":\"2020-11-24T10:03:06.000Z\"},{\"name\":\"Polaris Bank\",\"slug\":\"polaris-bank\",\"code\":\"076\",\"longcode\":\"076151006\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":13,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2016-07-14T10:04:29.000Z\"},{\"name\":\"Providus Bank\",\"slug\":\"providus-bank\",\"code\":\"101\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":25,\"createdAt\":\"2017-03-27T16:09:29.000Z\",\"updatedAt\":\"2021-02-09T17:50:06.000Z\"},{\"name\":\"Rand Merchant Bank\",\"slug\":\"rand-merchant-bank\",\"code\":\"502\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":176,\"createdAt\":\"2021-02-11T17:33:20.000Z\",\"updatedAt\":\"2021-02-11T17:33:20.000Z\"},{\"name\":\"Rubies MFB\",\"slug\":\"rubies-mfb\",\"code\":\"125\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":69,\"createdAt\":\"2020-01-25T09:49:59.000Z\",\"updatedAt\":\"2020-01-25T09:49:59.000Z\"},{\"name\":\"Sparkle Microfinance Bank\",\"slug\":\"sparkle-microfinance-bank\",\"code\":\"51310\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":72,\"createdAt\":\"2020-02-11T18:43:14.000Z\",\"updatedAt\":\"2020-02-11T18:43:14.000Z\"},{\"name\":\"Stanbic IBTC Bank\",\"slug\":\"stanbic-ibtc-bank\",\"code\":\"221\",\"longcode\":\"221159522\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":14,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:24:17.000Z\"},{\"name\":\"Standard Chartered Bank\",\"slug\":\"standard-chartered-bank\",\"code\":\"068\",\"longcode\":\"068150015\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":15,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:23:40.000Z\"},{\"name\":\"Sterling Bank\",\"slug\":\"sterling-bank\",\"code\":\"232\",\"longcode\":\"232150016\",\"gateway\":\"emandate\",\"pay_with_bank\":true,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":16,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2021-02-15T09:41:32.000Z\"},{\"name\":\"Suntrust Bank\",\"slug\":\"suntrust-bank\",\"code\":\"100\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":23,\"createdAt\":\"2016-10-10T17:26:29.000Z\",\"updatedAt\":\"2016-10-10T17:26:29.000Z\"},{\"name\":\"TAJ Bank\",\"slug\":\"taj-bank\",\"code\":\"302\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":68,\"createdAt\":\"2020-01-20T11:20:32.000Z\",\"updatedAt\":\"2020-01-20T11:20:32.000Z\"},{\"name\":\"TCF MFB\",\"slug\":\"tcf-mfb\",\"code\":\"51211\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":75,\"createdAt\":\"2020-04-03T09:34:35.000Z\",\"updatedAt\":\"2020-04-03T09:34:35.000Z\"},{\"name\":\"Titan Bank\",\"slug\":\"titan-bank\",\"code\":\"102\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":73,\"createdAt\":\"2020-03-10T11:41:36.000Z\",\"updatedAt\":\"2020-03-23T15:06:29.000Z\"},{\"name\":\"Union Bank of Nigeria\",\"slug\":\"union-bank-of-nigeria\",\"code\":\"032\",\"longcode\":\"032080474\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":17,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-02-18T20:22:54.000Z\"},{\"name\":\"United Bank For Africa\",\"slug\":\"united-bank-for-africa\",\"code\":\"033\",\"longcode\":\"033153513\",\"gateway\":\"emandate\",\"pay_with_bank\":true,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":18,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2020-12-01T10:28:56.000Z\"},{\"name\":\"Unity Bank\",\"slug\":\"unity-bank\",\"code\":\"215\",\"longcode\":\"215154097\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":19,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2019-07-22T12:44:02.000Z\"},{\"name\":\"VFD Microfinance Bank Limited\",\"slug\":\"vfd\",\"code\":\"566\",\"longcode\":\"\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":false,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":71,\"createdAt\":\"2020-02-11T15:44:11.000Z\",\"updatedAt\":\"2020-10-28T09:42:08.000Z\"},{\"name\":\"Wema Bank\",\"slug\":\"wema-bank\",\"code\":\"035\",\"longcode\":\"035150103\",\"gateway\":null,\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":20,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2021-02-09T17:49:59.000Z\"},{\"name\":\"Zenith Bank\",\"slug\":\"zenith-bank\",\"code\":\"057\",\"longcode\":\"057150013\",\"gateway\":\"emandate\",\"pay_with_bank\":false,\"active\":true,\"is_deleted\":null,\"country\":\"Nigeria\",\"currency\":\"NGN\",\"type\":\"nuban\",\"id\":21,\"createdAt\":\"2016-07-14T10:04:29.000Z\",\"updatedAt\":\"2021-03-25T13:06:57.000Z\"}]}";
//                break;
//            case "Resolve-BVN-Premium":
//                apiRes = "{\"data\":{\"residential_address\":\"no 13 coubams ajoah estate ikeja\",\"gender\":\"Male\",\"state_of_origin\":\"Delta State\",\"formatted_registration_date\":\"2015-03-31\",\"lga_of_origin\":\"Ughelli North\",\"title\":\"Mr\",\"lga_of_residence\":\"Ikeja\",\"nin\":\"\",\"mobile2\":\"\",\"bvn\":\"22218785179\",\"formatted_dob\":\"1993-10-31\",\"first_name\":\"SAMUEL\",\"email\":\"\",\"enrollment_bank\":{\"name\":\"Opportunity Bank Uganda Ltd\"},\"base_64_image\":\"sdhflejfojsdlfjdl\",\"mobile\":\"07064959838\",\"last_name\":\"EVUE\",\"is_blacklisted\":false,\"middle_name\":\"JESSE\",\"marital_status\":\"Single\",\"registration_date\":\"31-Mar-15\",\"nationality\":\"Nigeria\",\"dob\":\"31-Oct-93\",\"level_of_account\":\"Level 1 - Low Level Accounts\",\"name_on_card\":\"SAMUEL JESSE EVUE\"},\"meta\":{\"free_calls_left\":2,\"calls_this_month\":8},\"message\":\"BVN resolved\",\"status\":true}";
//                // {"status":true,"message":"BVN resolved","data":{"title":"Mr","first_name":"JOHN","middle_name":"MUKITE","last_name":"NAMEME","name_on_card":"MUKITE NAMEME","marital_status":"Married","dob":"17-Jun-80","formatted_dob":"1980-06-17","mobile":"08091111111","mobile2":"08090000000","registration_date":"24-Dec-16","formatted_registration_date":"2016-12-24","bvn":"00000000000","gender":"Male","lga_of_origin":"Ilesa West","state_of_origin":"Osun State","residential_address":"126 Joel Ogunnaike St Ikeja GRA, Lagos","lga_of_residence":"Ikeja","nationality":"Nigeria","email":"MUKITE@EXAMPLE.COM","is_blacklisted":false,"enrollment_bank":{"name":"First Bank of Nigeria","code":"011","enrollment_branch":"IKEJA BRANCH"},"level_of_account":"Level 2 - Medium Level Accounts","nin":"","base_64_image":"Base_64_Encoded_Image=="},"meta":{"calls_this_month":12,"free_calls_left":0}}
//                break;
//            case "Resolve-Account-Number":
//                // {"data":{"account_number":"2286544546","bank_id":21,"account_name":"SAMUEL JESSE EVUE"},"message":"Account number resolved","status":true}
//                apiRes = "{\"data\":{\"account_number\":\"2286544546\",\"bank_id\":21,\"account_name\":\"SAMUEL JESSE EVUE\"},\"message\":\"Account number resolved\",\"status\":true}";
//                break;
//            case "Check-Balance":
//                // {"data":[{"balance":1009000,"currency":"NGN"},{"balance":0,"currency":"USD"}],"message":"Balances retrieved","status":true}
//                apiRes = "{\"status\":true,\"message\":\"Balances retrieved\",\"data\":[{\"currency\":\"NGN\",\"balance\":1700000}]}";
//                break;
//            case "Charge-Authorization":
//                // {"data":{"transaction_date":"2021-04-27T03:29:53.000Z","amount":500,"metadata":"","fees":8,"channel":"card","gateway_response":"Approved","reference":"20210427112946836564782633975808","authorization":{"last4":"9776","signature":"SIG_yftHv4NxQ3zTRZyvTeiK","bin":"539941","channel":"card","exp_month":"12","exp_year":"2024","card_type":"mastercard DEBIT","reusable":true,"country_code":"NG","bank":"Zenith Bank","authorization_code":"AUTH_aqthd97ubg","brand":"mastercard"},"domain":"live","currency":"NGN","id":1101408594,"status":"success","customer":{"risk_action":"default","id":43721984,"customer_code":"CUS_xmr4aa0hb3kj6d7","email":"1179da3a29@lcserver.com"}},"message":"Charge attempted","status":true}
//                // {"data":{"transaction_date":"2021-05-10T09:38:56.000Z","amount":47000,"metadata":"","channel":"card","gateway_response":"Insufficient Funds","reference":"2021051017385212706523136","authorization":{"last4":"5811","signature":"SIG_H8XXPH3ctaSpZCpzExF0","bin":"533477","channel":"card","exp_month":"01","exp_year":"2024","card_type":"mastercard DEBIT","reusable":true,"country_code":"NG","bank":"Sterling Bank","authorization_code":"AUTH_zf6leet1tz","account_name":"INNOCENT ENO SYLVANUS","brand":"mastercard"},"domain":"live","currency":"NGN","id":1121534100,"status":"failed","customer":{"risk_action":"default","id":44325378,"customer_code":"CUS_hzkcqkt5bmbrbpo","email":"f4e94b2e74@lcserver.com"}},"message":"Charge attempted","status":true}
//                // apiRes = "{\"status\":true,\"message\":\"Charge attempted\",\"data\":{\"amount\":27000,\"currency\":\"NGN\",\"transaction_date\":\"2020-05-27T11:45:03.000Z\",\"status\":\"success\",\"reference\":\"cn65lf4ixmkzvda\",\"domain\":\"test\",\"metadata\":\"\",\"gateway_response\":\"Approved\",\"message\":null,\"channel\":\"card\",\"ip_address\":null,\"log\":null,\"fees\":14500,\"authorization\":{\"authorization_code\":\"AUTH_pmx3mgawyd\",\"bin\":\"408408\",\"last4\":\"4081\",\"exp_month\":\"12\",\"exp_year\":\"2020\",\"channel\":\"card\",\"card_type\":\"visa DEBIT\",\"bank\":\"Test Bank\",\"country_code\":\"NG\",\"brand\":\"visa\",\"reusable\":true,\"signature\":\"SIG_2Gvc6pNuzJmj4TCchXfp\",\"account_name\":null},\"customer\":{\"id\":23215815,\"first_name\":null,\"last_name\":null,\"email\":\"mail@mail.com\",\"customer_code\":\"CUS_wt0zmhzb0xqd4nr\",\"phone\":null,\"metadata\":null,\"risk_action\":\"default\"},\"plan\":null,\"id\":696105928}}";
//                apiRes = iSysConfigService.selectConfigByKey("Charge-Authorization");
//                break;
//            case "Verify-Transaction":
////                Response response2 = client.newCall(request).execute();
////                apiRes = response2.body().string().toString();
////                log.info("外部接口 {} 返回报文：{}", apiName, apiRes);
//                // {"data":{"metadata":"","fees":75,"log":{"start_time":1619436249,"input":[],"success":true,"mobile":true,"history":[{"time":17,"type":"input","message":"Filled this field: card number"},{"time":23,"type":"input","message":"Filled this field: card expiry"},{"time":39,"type":"input","message":"Filled this field: card cvv"},{"time":39,"type":"action","message":"Attempted to pay with card"},{"time":41,"type":"auth","message":"Authentication Required: 3DS"},{"time":43,"type":"action","message":"Third-party authentication window opened"},{"time":179,"type":"success","message":"Successfully paid with card"}],"errors":0,"time_spent":179,"attempts":1,"authentication":"3DS"},"channel":"card","created_at":"2021-04-26T11:09:11.000Z","gateway_response":"Approved","requested_amount":5000,"reference":"20210426190907836317994048028672","authorization":{"last4":"9776","signature":"SIG_yftHv4NxQ3zTRZyvTeiK","bin":"539941","channel":"card","exp_month":"12","exp_year":"2024","card_type":"mastercard DEBIT","reusable":true,"country_code":"NG","bank":"Zenith Bank","authorization_code":"AUTH_aqthd97ubg","brand":"mastercard"},"createdAt":"2021-04-26T11:09:11.000Z","split":{},"currency":"NGN","id":1100328200,"transaction_date":"2021-04-26T11:09:11.000Z","amount":5000,"subaccount":{},"ip_address":"168.63.252.224","message":"","paid_at":"2021-04-26T11:27:06.000Z","domain":"live","paidAt":"2021-04-26T11:27:06.000Z","plan_object":{},"status":"success","customer":{"risk_action":"default","id":43721984,"customer_code":"CUS_xmr4aa0hb3kj6d7","email":"1179da3a29@lcserver.com"}},"message":"Verification successful","status":true}
//                // {"status":true,"message":"Verification successful","data":{"id":1100348812,"domain":"live","status":"abandoned","reference":"20210426192231836321365404418048","amount":5000,"message":null,"gateway_response":"The transaction was not completed","paid_at":null,"created_at":"2021-04-26T11:22:35.000Z","channel":"card","currency":"NGN","ip_address":"219.134.114.117","metadata":"","log":null,"fees":null,"fees_split":null,"authorization":{},"customer":{"id":43721984,"first_name":null,"last_name":null,"email":"1179da3a29@lcserver.com","customer_code":"CUS_xmr4aa0hb3kj6d7","phone":null,"metadata":null,"risk_action":"default","international_format_phone":null},"plan":null,"split":{},"order_id":null,"paidAt":null,"createdAt":"2021-04-26T11:22:35.000Z","requested_amount":5000,"pos_transaction_data":null,"transaction_date":"2021-04-26T11:22:35.000Z","plan_object":{},"subaccount":{}}}
//                // apiRes = "{\"status\":true,\"message\":\"Verification successful\",\"data\":{\"id\":1060800740,\"domain\":\"test\",\"status\":\"success\",\"reference\":\"129123kdke203u92374esfs\",\"amount\":500000,\"message\":null,\"gateway_response\":\"Successful\",\"paid_at\":\"2021-03-30T02:35:57.000Z\",\"created_at\":\"2021-03-30T02:31:54.000Z\",\"channel\":\"card\",\"currency\":\"NGN\",\"ip_address\":\"58.250.250.192\",\"metadata\":\"\",\"log\":{\"start_time\":1617071542,\"time_spent\":216,\"attempts\":3,\"errors\":2,\"success\":true,\"mobile\":false,\"input\":[],\"history\":[{\"type\":\"action\",\"message\":\"Set payment method to: bank\",\"time\":20},{\"type\":\"action\",\"message\":\"Set payment method to: ussd\",\"time\":22},{\"type\":\"action\",\"message\":\"Set payment method to: card\",\"time\":24},{\"type\":\"action\",\"message\":\"Set payment method to: bank\",\"time\":56},{\"type\":\"input\",\"message\":\"Filled this field: account number\",\"time\":69},{\"type\":\"input\",\"message\":\"Changed this field: account number\",\"time\":88},{\"type\":\"action\",\"message\":\"Attempted to pay with bank account\",\"time\":88},{\"type\":\"error\",\"message\":\"Error: Our Test Bank account for eMandate is\\nZenith Bank\\nAccount:0000000000\\nToken:123456\",\"time\":92},{\"type\":\"action\",\"message\":\"Third-party authentication window opened\",\"time\":114},{\"type\":\"action\",\"message\":\"Third-party authentication window closed\",\"time\":116},{\"type\":\"input\",\"message\":\"Changed this field: account number\",\"time\":159},{\"type\":\"action\",\"message\":\"Attempted to pay with bank account\",\"time\":159},{\"type\":\"error\",\"message\":\"Error: Our Test Bank account for eMandate is\\nZenith Bank\\nAccount:0000000000\\nToken:123456\",\"time\":160},{\"type\":\"input\",\"message\":\"Changed this field: account number\",\"time\":168},{\"type\":\"action\",\"message\":\"Set payment method to: card\",\"time\":210},{\"type\":\"action\",\"message\":\"Attempted to pay with card\",\"time\":214},{\"type\":\"success\",\"message\":\"Successfully paid with card\",\"time\":216}]},\"fees\":17500,\"fees_split\":null,\"authorization\":{\"authorization_code\":\"AUTH_l7h4o5y68z\",\"bin\":\"408408\",\"last4\":\"4081\",\"exp_month\":\"12\",\"exp_year\":\"2030\",\"channel\":\"card\",\"card_type\":\"visa \",\"bank\":\"TEST BANK\",\"country_code\":\"NG\",\"brand\":\"visa\",\"reusable\":true,\"signature\":\"SIG_83KWYHFneVByoHFsx0nq\",\"account_name\":null},\"customer\":{\"id\":42216304,\"first_name\":null,\"last_name\":null,\"email\":\"jamnsin@qq.com\",\"customer_code\":\"CUS_gwgg9tt1acphbzs\",\"phone\":null,\"metadata\":null,\"risk_action\":\"default\",\"international_format_phone\":null},\"plan\":null,\"split\":{},\"order_id\":null,\"paidAt\":\"2021-03-30T02:35:57.000Z\",\"createdAt\":\"2021-03-30T02:31:54.000Z\",\"requested_amount\":500000,\"pos_transaction_data\":null,\"transaction_date\":\"2021-03-30T02:31:54.000Z\",\"plan_object\":{},\"subaccount\":{}}}";
//                apiRes = iSysConfigService.selectConfigByKey("Verify-Transaction");
//                break;
//            case "Verify-Transfer":
//                //{"data":{"reason":"User withdrawal","amount":500,"source":"balance","transfer_code":"TRF_6823k7kybi9dm83","reference":"n6vkpvmkxy","createdAt":"2021-04-26T09:08:17.225Z","domain":"live","integration":592332,"recipient":13798462,"currency":"NGN","id":58651286,"status":"pending","updatedAt":"2021-04-26T09:08:17.225Z"},"message":"Transfer has been queued","status":true}
//                //{"status":true,"message":"Transfer retrieved","data":{"amount":500,"createdAt":"2021-04-26T09:33:45.000Z","currency":"NGN","domain":"live","failures":null,"id":58653860,"integration":592332,"reason":"User withdrawal","reference":"20210426173321836293891345874944","source":"balance","source_details":null,"status":"success","titan_code":null,"transfer_code":"TRF_2in22vuxzhxhtmm","transferred_at":"2021-04-26T09:34:04.000Z","updatedAt":"2021-04-26T09:34:04.000Z","recipient":{"active":true,"createdAt":"2021-04-23T13:14:06.000Z","currency":"NGN","description":"Samuel Jesse Evue","domain":"live","email":null,"id":13798462,"integration":592332,"metadata":null,"name":"Samuel Jesse Evue","recipient_code":"RCP_e3h3qko8ccekx64","type":"nuban","updatedAt":"2021-04-23T13:14:06.000Z","is_deleted":false,"details":{"authorization_code":null,"account_number":"2286544546","account_name":"SAMUEL JESSE EVUE","bank_code":"057","bank_name":"Zenith Bank"}},"session":{"provider":"nip","id":"110006210426093345005865386001"}}}
//                apiRes = "{\"status\":true,\"message\":\"Transfer retrieved\",\"data\":{\"integration\":119333,\"recipient\":{\"domain\":\"test\",\"type\":\"nuban\",\"currency\":\"NGN\",\"name\":\"Zombie\",\"details\":{\"account_number\":\"0100000001\",\"account_name\":null,\"bank_code\":\"044\",\"bank_name\":\"Access Bank\"},\"description\":\"Zombier\",\"metadata\":\"\",\"recipient_code\":\"RCP_c2mty1w1uvd4av4\",\"active\":true,\"email\":null,\"id\":31911,\"integration\":119333,\"createdAt\":\"2017-10-13T20:35:51.000Z\",\"updatedAt\":\"2017-10-13T20:35:51.000Z\"},\"domain\":\"test\",\"amount\":200000,\"currency\":\"NGN\",\"reference\":\"ref_demo\",\"source\":\"balance\",\"source_details\":null,\"reason\":\"Test for reference\",\"status\":\"success\",\"failures\":null,\"transfer_code\":\"TRF_kjati32r73poyt5\",\"titan_code\":null,\"transferred_at\":null,\"id\":476948,\"createdAt\":\"2018-07-22T10:29:33.000Z\",\"updatedAt\":\"2018-07-22T10:29:33.000Z\"}}";
//                break;
//            case "Initiate-Transfer":
//                // {"message":"Recipient specified is invalid","status":false}
//                apiRes = "{\"status\":true,\"message\":\"Transfer requires OTP to continue\",\"data\":{\"integration\":100073,\"domain\":\"test\",\"amount\":200000,\"currency\":\"NGN\",\"source\":\"balance\",\"reason\":\"Calm down\",\"recipient\":28,\"status\":\"otp\",\"transfer_code\":\"TRF_1ptvuv321ahaa7q\",\"id\":14,\"createdAt\":\"2017-02-03T17:21:54.508Z\",\"updatedAt\":\"2017-02-03T17:21:54.508Z\"}}";
//                break;
//            case "Create-Transfer-Recipient":
//                // {"data":{"active":true,"description":"Samuel Jesse Evue","type":"nuban","createdAt":"2021-04-23T13:14:06.580Z","is_deleted":false,"domain":"live","integration":592332,"name":"Samuel Jesse Evue","currency":"NGN","details":{"account_number":"2286544546","bank_code":"057","account_name":"SAMUEL JESSE EVUE","bank_name":"Zenith Bank"},"id":13798462,"recipient_code":"RCP_e3h3qko8ccekx64","updatedAt":"2021-04-23T13:14:06.580Z"},"message":"Transfer recipient created successfully","status":true}
//                apiRes = "{\"status\":true,\"message\":\"Recipient created\",\"data\":{\"type\":\"nuban\",\"name\":\"Zombie\",\"description\":\"Zombier\",\"metadata\":{\"job\":\"Flesh Eater\"},\"domain\":\"test\",\"details\":{\"account_number\":\"0100000010\",\"account_name\":null,\"bank_code\":\"044\",\"bank_name\":\"Access Bank\"},\"currency\":\"NGN\",\"recipient_code\":\"RCP_1i2k27vk4suemug\",\"active\":true,\"id\":27,\"createdAt\":\"2017-02-02T19:35:33.686Z\",\"updatedAt\":\"2017-02-02T19:35:33.686Z\"}}";
//                break;
//            case "Bank-Coverage":
//                // {"status":"success","message":"Banks successfully retrieved","data":{"banks":[{"id":"5d6fe57a4099cc4b210bbeb1","name":"First Bank of Nigeria","slug":"first-bank-of-nigeria","icon":"https://okra-images.s3.eu-west-3.amazonaws.com/First+Bank+Nigeria+Logo+Color.svg","v2_icon":"","v2_logo":"","products":["auth","balance","transactions","income","identity","direct-debit ","periodic-transactions","periodic-balance"],"colors":{"primary":"#162D4C","accent":"#DFAC0F","bg":"#295590","button":"#162D4C","icon":"#162D4C"},"secret_question_or_otp":true,"secret_question_or_otp_mobile":false,"secret_question_or_otp_corp":true,"ussd":true,"countries":["NG"],"corporate":true,"status":"healthy","individual":true,"created_at":"2019-09-04T10:04:29.000Z","last_updated":"2021-04-29T12:03:33.563Z"},{"id":"5d6fe57a4099cc4b210bbeae","name":"Ecobank Nigeria","slug":"ecobank-nigeria","icon":"https://okra-images.s3.eu-west-3.amazonaws.com/Ecobank+Logo+Color.svg","v2_icon":"","v2_logo":"","products":["auth","balance","transactions","income","identity","direct-debit ","periodic-transactions","periodic-balance"],"colors":{"primary":"#00577A","accent":"#BED602","bg":"#007CB3","button":"#0082BB","icon":"#00577A"},"secret_question_or_otp":false,"secret_question_or_otp_mobile":false,"secret_question_or_otp_corp":false,"ussd":true,"countries":["NG"],"corporate":true,"status":"healthy","individual":true,"created_at":"2019-09-04T10:04:29.000Z","last_updated":"2021-04-29T11:34:09.437Z"},{"id":"5d6fe57a4099cc4b210bbeb0","name":"Fidelity Bank","slug":"fidelity-bank","icon":"https://okra-images.s3.eu-west-3.amazonaws.com/Fidelity+Bank+Nigeria+Logo+Color.svg","products":["auth","balance","transactions","income","identity","direct-debit ","guarantors ","periodic-transactions","periodic-balance"],"colors":{"accent":"#4DC247","primary":"#010C42","button":"#11237D"},"secret_question_or_otp":false,"secret_question_or_otp_mobile":false,"secret_question_or_otp_corp":false,"ussd":false,"countries":["NG"],"status":"healthy","individual":true,"created_at":"2019-09-04T10:04:29.000Z","last_updated":"2021-04-26T12:39:33.827Z"}],"credentials":null}}
//                apiRes = "{\"status\":\"success\",\"message\":\"Banks successfully retrieved\",\"data\":{\"banks\":[{\"id\":\"5d6fe57a4099cc4b210bbeb1\",\"name\":\"First Bank of Nigeria\",\"slug\":\"first-bank-of-nigeria\",\"icon\":\"https://okra-images.s3.eu-west-3.amazonaws.com/First+Bank+Nigeria+Logo+Color.svg\",\"v2_icon\":\"\",\"v2_logo\":\"\",\"products\":[\"auth\",\"balance\",\"transactions\",\"income\",\"identity\",\"direct-debit \",\"periodic-transactions\",\"periodic-balance\"],\"colors\":{\"primary\":\"#162D4C\",\"accent\":\"#DFAC0F\",\"bg\":\"#295590\",\"button\":\"#162D4C\",\"icon\":\"#162D4C\"},\"secret_question_or_otp\":true,\"secret_question_or_otp_mobile\":false,\"secret_question_or_otp_corp\":true,\"ussd\":true,\"countries\":[\"NG\"],\"corporate\":true,\"status\":\"healthy\",\"individual\":true,\"created_at\":\"2019-09-04T10:04:29.000Z\",\"last_updated\":\"2021-04-29T12:03:33.563Z\"},{\"id\":\"5d6fe57a4099cc4b210bbeae\",\"name\":\"Ecobank Nigeria\",\"slug\":\"ecobank-nigeria\",\"icon\":\"https://okra-images.s3.eu-west-3.amazonaws.com/Ecobank+Logo+Color.svg\",\"v2_icon\":\"\",\"v2_logo\":\"\",\"products\":[\"auth\",\"balance\",\"transactions\",\"income\",\"identity\",\"direct-debit \",\"periodic-transactions\",\"periodic-balance\"],\"colors\":{\"primary\":\"#00577A\",\"accent\":\"#BED602\",\"bg\":\"#007CB3\",\"button\":\"#0082BB\",\"icon\":\"#00577A\"},\"secret_question_or_otp\":false,\"secret_question_or_otp_mobile\":false,\"secret_question_or_otp_corp\":false,\"ussd\":true,\"countries\":[\"NG\"],\"corporate\":true,\"status\":\"healthy\",\"individual\":true,\"created_at\":\"2019-09-04T10:04:29.000Z\",\"last_updated\":\"2021-04-29T11:34:09.437Z\"},{\"id\":\"5d6fe57a4099cc4b210bbeb0\",\"name\":\"Fidelity Bank\",\"slug\":\"fidelity-bank\",\"icon\":\"https://okra-images.s3.eu-west-3.amazonaws.com/Fidelity+Bank+Nigeria+Logo+Color.svg\",\"products\":[\"auth\",\"balance\",\"transactions\",\"income\",\"identity\",\"direct-debit \",\"guarantors \",\"periodic-transactions\",\"periodic-balance\"],\"colors\":{\"accent\":\"#4DC247\",\"primary\":\"#010C42\",\"button\":\"#11237D\"},\"secret_question_or_otp\":false,\"secret_question_or_otp_mobile\":false,\"secret_question_or_otp_corp\":false,\"ussd\":false,\"countries\":[\"NG\"],\"status\":\"healthy\",\"individual\":true,\"created_at\":\"2019-09-04T10:04:29.000Z\",\"last_updated\":\"2021-04-26T12:39:33.827Z\"}],\"credentials\":null}}";
//                break;
//            case "NUBAN-Identity-Verification":
//                // {"status":"success","message":"Identity successfully retrieved","data":{"fullname":"Monica Emily Simpson","firstname":"Monica","lastname":"Simpson","middlename":"Emily","id":"608a9e463ccd9905356ad36d","bvn":"22245660958","score":73,"env":"production-sandbox","created_at":"2021-04-29T11:53:42.456Z","last_updated":"2021-04-29T11:53:42.456Z","aliases":["Mary  Williams Rockfeller","Friday Ford"],"customer":"608a9e463ccd9905356ad36e","dob":"2020-10-14T00:18:00+00:00","gender":"F","phone":["09924457172","08265644794"],"email":["Paige_Feeney@yahoo.com","Darien_Rohan@gmail.com"],"address":["3385 Mr., Celestine Rockfeller Pines, Enugu East Kaduna"],"verified":true,"photo_id":[{"_id":"608a9e463ccd9905356ad36f","url":"iVBORw0KGgoAAAANSUhEUgAAAdQAAAEHCAMAAAAgU0ffAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAELUExURezv4uzu","image_type":"ID"},{"_id":"608a9e463ccd9905356ad370","url":"iVBORw0KGgoAAAANSUhEUgAAAZ0AAAH0CAYAAAGRI8CmAACAAElEQVR42uzdd3wU1drA8d+ZLakEQu+9Iy27m6WDvV0VxN7F3nvv","image_type":"bvn_photo"}],"status":"true"}}
//                apiRes = "{\"status\":\"success\",\"message\":\"Identity successfully retrieved\",\"data\":{\"fullname\":\"Monica Emily Simpson\",\"firstname\":\"Monica\",\"lastname\":\"Simpson\",\"middlename\":\"Emily\",\"id\":\"608a9e463ccd9905356ad36d\",\"bvn\":\"22245660958\",\"score\":73,\"env\":\"production-sandbox\",\"created_at\":\"2021-04-29T11:53:42.456Z\",\"last_updated\":\"2021-04-29T11:53:42.456Z\",\"aliases\":[\"Mary  Williams Rockfeller\",\"Friday Ford\"],\"customer\":\"608a9e463ccd9905356ad36e\",\"dob\":\"2020-10-14T00:18:00+00:00\",\"gender\":\"F\",\"phone\":[\"09924457172\",\"08265644794\"],\"email\":[\"Paige_Feeney@yahoo.com\",\"Darien_Rohan@gmail.com\"],\"address\":[\"3385 Mr., Celestine Rockfeller Pines, Enugu East Kaduna\"],\"verified\":true,\"photo_id\":[{\"_id\":\"608a9e463ccd9905356ad36f\",\"url\":\"iVBORw0KGgoAAAANSUhEUgAAAdQAAAEHCAMAAAAgU0ffAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAELUExURezv4uzu\",\"image_type\":\"ID\"},{\"_id\":\"608a9e463ccd9905356ad370\",\"url\":\"iVBORw0KGgoAAAANSUhEUgAAAZ0AAAH0CAYAAAGRI8CmAACAAElEQVR42uzdd3wU1drA8d+ZLakEQu+9Iy27m6WDvV0VxN7F3nvv\",\"image_type\":\"bvn_photo\"}],\"status\":\"true\"}}";
//                break;
//            default:

        return JSON.parseObject(apiRes);
    }

    private boolean extApiMock() {
        return Integer.parseInt(getDictLable("biz_switch", "api_paystack_mock")) == 1;
    }

    private void updateExtTransferRst(Long rstId, JSONObject data, String eventType, String eventSource, String custNo) {
        ExtTransferResult transferResult = getExtTransferResult(data, eventType, eventSource);
        transferResult.setId(rstId);
        transferResult.setCustNo(custNo);
        transferResultService.updateById(transferResult);
    }

    private void saveExtTransferRst(JSONObject data, String eventType, String eventSource, String custNo) {
        ExtTransferResult transferResult = getExtTransferResult(data, eventType, eventSource);
        transferResult.setStatus(0);//mq dengda
        transferResult.setCustNo(custNo);
        transferResultService.save(transferResult);
    }

    private ExtTransferResult getExtTransferResult(JSONObject data, String eventType, String eventSource) {
        ExtTransferResult transferResult = new ExtTransferResult();
        transferResult.setEventType(eventType);
        transferResult.setEventSource(eventSource);
        transferResult.setTransId(getValue(data, "id"));
        transferResult.setSerialNo(getValue(data, "reference"));
        transferResult.setTransStatus(getValue(data, "status"));
        transferResult.setAmount(getValue(data, "amount"));
        transferResult.setGatewayResponse(getValue(data, "gateway_response"));
        transferResult.setCreatedAt(getValue(data, "created_at"));
        transferResult.setChannel(getValue(data, "channel"));
        transferResult.setCurrency(getValue(data, "currency"));
        transferResult.setIpAddress(getValue(data, "ip_address"));
        transferResult.setHistory(JSON.toJSONString(data.getJSONObject("log")));
        transferResult.setFees(getValue(data, "fees"));
        transferResult.setUpdatedat(getValue(data, "updated_at"));
        transferResult.setPaidAt(getValue(data, "paid_at"));
        transferResult.setRequestedAmount(getValue(data, "requested_amount"));
        transferResult.setRemark(getValue(data, "failures"));

        if (eventType.contains("transfer")) {
            transferResult.setSource(getValue(data, "source"));
            transferResult.setTransferCode(getValue(data, "transfer_code"));
            transferResult.setTransactionDate(getValue(data, "transferred_at"));

            JSONObject recipient = data.getJSONObject("recipient");
            if (recipient != null && recipient.size() > 0) {
                transferResult.setRecipientCode(getValue(recipient, "recipient_code"));

                JSONObject details = data.getJSONObject("details");
                if (details != null && details.size() > 0) {
                    transferResult.setAuthorizationCode(getValue(details, "authorization_code"));
                    transferResult.setAccountNumber(getValue(details, "account_number"));
                    transferResult.setAccountName(getValue(details, "account_name"));
                    transferResult.setBankCode(getValue(details, "bank_code"));
                    transferResult.setBankName(getValue(details, "bank_name"));
                }
            }
        } else {
            transferResult.setTransactionDate(getValue(data, "transaction_date"));
            transferResult.setSource(JSON.toJSONString(data.getJSONObject("source")));
        }
        transferResult.setDomain(getValue(data, "domain"));
        transferResult.setIntegration(JSON.toJSONString(data.getJSONObject("integration")));
        transferResult.setReason(getValue(data, "reason"));

        JSONObject authorization = data.getJSONObject("authorization");
        if (authorization != null && authorization.size() > 0) {
            transferResult.setAccountName(getValue(authorization, "account_name"));
            transferResult.setAuthorizationCode(getValue(authorization, "authorization_code"));
            transferResult.setBin(getValue(authorization, "bin"));
            transferResult.setLast4(getValue(authorization, "last4"));
            transferResult.setExpMonth(getValue(authorization, "exp_month"));
            transferResult.setExpYear(getValue(authorization, "exp_year"));
            transferResult.setChannel(getValue(authorization, "channel"));
            transferResult.setCardType(getValue(authorization, "card_type"));
            transferResult.setBankName(getValue(authorization, "bank").trim());
            transferResult.setBankCode(bankService.getBankCode(transferResult.getBankName()));
            transferResult.setCountryCode(getValue(authorization, "country_code"));
            transferResult.setBrand(getValue(authorization, "brand"));
            transferResult.setReusable(getValue(authorization, "reusable"));
        }

        JSONObject customer = data.getJSONObject("customer");
        if (customer != null && customer.size() > 0) {
            transferResult.setFirstName(getValue(customer, "first_name"));
            transferResult.setMiddleName(getValue(customer, "middle_name"));
            transferResult.setLastName(getValue(customer, "last_name"));
            transferResult.setPhone(getValue(customer, "phone"));
            transferResult.setInternationalFormatPhone(getValue(customer, "international_format_phone"));
            transferResult.setCustomerCode(getValue(customer, "customer_code"));
            transferResult.setRiskAction(getValue(customer, "risk_action"));
            transferResult.setEmail(getValue(customer, "email"));
        }

        JSONObject log = data.getJSONObject("log");
        if (log != null && log.size() > 0) {
            transferResult.setTimeSpent(Long.valueOf(getValue(log, "time_spent")));
            transferResult.setAttempts(getValue(log, "attempts"));
            transferResult.setAuthentication(getValue(log, "authentication"));
        }

        return transferResult;
    }

    private String getValue(JSONObject json, String fieldName) {
        return json.get(fieldName) == null ? "" : json.getString(fieldName);
    }

    private String initUrlParam(JSONObject reqParam) {
        List<String> paramList = new ArrayList<>();
        reqParam.forEach((k, v) -> {
            paramList.add(k + "=" + v);
        });

        String reqData = String.join("&", paramList);

        return reqData;
    }

}
